#include "SDL.h"

#include <fstream>
#include <iostream>
#include <array>
#include <optional>
#include <cmath>
using namespace std;

SDL_Window* window = nullptr;
SDL_Renderer* renderer = nullptr;
SDL_Event event;

constexpr int Width = 720;
constexpr int Height = 480;
constexpr int TileSize = Height / 8;
constexpr SDL_Point CanvaPos = {
    Width / 2 - TileSize * 4, Height / 2 - TileSize * 4
};

optional<SDL_Point> CalcTilePos(const SDL_Point& pos) {
    SDL_Point p = {
        (int)floor((pos.x - CanvaPos.x) / static_cast<float>(TileSize)),
        (int)floor((pos.y - CanvaPos.y) / static_cast<float>(TileSize))
    };
    if (p.x >= 0 && p.x < 8 && p.y >= 0 && p.y < 8)
        return p;
    return std::nullopt;
}

SDL_Rect ConvertTilePos2RealPos(const SDL_Point& tilePos) {
    return {
        tilePos.x * TileSize + CanvaPos.x,
        tilePos.y * TileSize + CanvaPos.y,
        TileSize, TileSize
    };
}

void SaveFont(const array<bool, 8 * 8>& data) {
    ofstream file("font.txt");
    file << "{" << endl;
    for (int y = 0; y < 8; y++) {
        for (int x = 0; x < 8; x++) {
            if (data.at(x + y * 8)) {
                file << "1,";
            } else {
                file << "0,";
            }
        }
        file << endl;
    }
    file << "}";
    file.close();

    SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION, "save OK", "save OK", nullptr);
}

int main(int argc, char** argv) {
    SDL_Init(SDL_INIT_EVERYTHING);

    window = SDL_CreateWindow(
                "FontEditor",
                SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
                Width, Height,
                SDL_WINDOW_SHOWN
             );

    renderer = SDL_CreateRenderer(window, -1, 0);

    bool isQuit = false;

    SDL_Point mousePos;

    array<bool, 8 * 8> data;
    data.fill(false);

    bool leftButtonDown = false;
    bool rightButtonDown = false;

    while (!isQuit) {
        SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
        SDL_RenderClear(renderer);

        while (SDL_PollEvent(&event)) {
            if (event.type == SDL_QUIT) {
                isQuit = true;
            }
            if (event.type == SDL_MOUSEMOTION) {
                mousePos.x = event.motion.x;
                mousePos.y = event.motion.y;

                auto pos = CalcTilePos(mousePos);
                if (leftButtonDown) {
                    if (pos)
                        data.at(pos->y * 8 + pos->x) = true;
                }
                if (rightButtonDown) {
                    if (pos)
                        data.at(pos->y * 8 + pos->x) = false;
                }
            }
            if (event.type == SDL_MOUSEBUTTONDOWN) {
                if (event.button.button == SDL_BUTTON_LEFT)
                    leftButtonDown = true;
                if (event.button.button == SDL_BUTTON_RIGHT)
                    rightButtonDown = true;
                auto pos = CalcTilePos(mousePos);
                if (leftButtonDown) {
                    if (pos)
                        data.at(pos->y * 8 + pos->x) = true;
                }
                if (rightButtonDown) {
                    if (pos)
                        data.at(pos->y * 8 + pos->x) = false;
                }
            }
            if (event.type == SDL_MOUSEBUTTONUP) {
                if (event.button.button == SDL_BUTTON_LEFT)
                    leftButtonDown = false;
                if (event.button.button == SDL_BUTTON_RIGHT)
                    rightButtonDown = false;
            }
            if (event.type == SDL_KEYDOWN) {
                if (event.key.keysym.sym == SDLK_RETURN)
                    SaveFont(data);
                if (event.key.keysym.sym == SDLK_c)
                    data.fill(false);
            }
        }

        for (int i = 0; i < data.size(); i++) {
            if (data[i]) {
                SDL_Rect rect = ConvertTilePos2RealPos({i % 8, i / 8});
                SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
                SDL_RenderFillRect(renderer, &rect);
            }
        }

        auto pos = CalcTilePos(mousePos);
        if (pos) {
            SDL_Rect rect = ConvertTilePos2RealPos(pos.value());
            SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
            SDL_RenderFillRect(renderer, &rect);
        }

        SDL_Rect rect = {CanvaPos.x, CanvaPos.y, TileSize * 8, TileSize * 8};
        SDL_SetRenderDrawColor(renderer, 0, 255, 255, 255);
        SDL_RenderDrawRect(renderer, &rect);

        SDL_RenderPresent(renderer);
        SDL_Delay(10);
    }

    SDL_Quit();
    return 0;
}
